package sk.fiit.vppj.eventmanager.data;

import java.util.Collections;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import sk.fiit.vppj.eventmanager.core.DatabaseManager;

/**
 * Data class, which represents user role Judge. Extends class User. The class is immutable.
 * 
 * @author Marek
 * 
 */
public class User {
	protected Map<String, Object> data = null;
	private int id = 0;
	private final static Logger log = Logger.getLogger( User.class.getName() );

	public User(int id, String clazz) {
		setData( id, clazz );
		this.id = id;
		if( this.data == null ) {
			log.log( Level.INFO, "Selected user is not in database! id = ? and class = ?", new Object[] { this.id, clazz } );
			throw new NullPointerException( "User was not set!" );
		}
	}

	private void setData(int id, String clazz) {
		final String sql = "SELECT jos_users.id, jos_users.name, jos_users.username, jos_users.email,"
				+ " jos_event_manager_users.*, jos_event_manager_states.name AS stateName, "
				+ getUserClassTable( clazz ) + ".* FROM jos_users JOIN jos_event_manager_users ON "
				+ "(jos_users.id = jos_event_manager_users.user_id) JOIN "
				+ getUserClassTable( clazz )
				+ " ON jos_users.id = "
				+ getUserClassTable( clazz )
				+ ".user_id JOIN jos_event_manager_states ON (jos_event_manager_states.IDState = jos_event_manager_users.state_id)  WHERE jos_users.id = ? ";

		this.data = Collections.unmodifiableMap( DatabaseManager.getInstance().getJdbcTemplate().queryForMap( sql, new Object[] { id } ) );
	}

	private String getUserClassTable(String clazz) {
		String classTable = null;

		if( clazz.equals( "participant" ) ) {
			classTable = "jos_event_manager_participants";
		}
		else if( clazz.equals( "supervisor" ) ) {
			classTable = "jos_event_manager_supervisors";
		}
		else if( clazz.equals( "judge" ) ) {
			classTable = "jos_event_manager_judges";
		}
		else if( clazz.equals( "volunteer" ) ) {
			classTable = "jos_event_manager_volunteers";
		}
		else {
			log.log( Level.WARNING, "Undefined user tries to be find in database" );
			throw new IllegalStateException( "Undefined user class!" );
		}
		return classTable;
	}

	public int getId() {
		return Integer.parseInt( this.data.get( "id" ).toString() );
	}

	public String getName() {
		return this.data.get( "name" ).toString();
	}

	public String getUsername() {
		return this.data.get( "username" ).toString();
	}

	public String getEmail() {
		return this.data.get( "email" ).toString();
	}

	// TODO not implemented
	public int getAccomodation() {
		return Integer.parseInt( this.data.get( "room_id" ).toString() );
	}

	public Trip getEsiTour() {
		int id = Integer.parseInt( this.data.get( "esiTour_id" ).toString() );
		if( id == 0 ) {
			return null;
		}
		return new Trip( id );
	}

	public Trip getFuntrip() {
		int id = Integer.parseInt( this.data.get( "funtrip_id" ).toString() );
		if( id == 0 ) {
			return null;
		}
		return new Trip( id );
	}

	public String getClazz() {
		return this.data.get( "class" ).toString();
	}
	
	public String getGroup_id() {
		return this.data.get( "group_id" ).toString();
	}
	
	public String getGroupName() {
		
		if(Integer.parseInt( this.data.get( "group_id" ).toString() ) == 0)
		{
			return "";
		}
		else
		{
			return (String) DatabaseManager.getInstance().getJdbcTemplate().queryForObject( "SELECT g.name FROM jos_event_manager_groups AS g WHERE g.IDGroup = ?", new Object[]{Integer.parseInt( this.data.get( "group_id" ).toString() )}, String.class);
		}
		
	}

	public String getSex() {
		return this.data.get( "sex" ).toString();
	}

	public String getAddress() {
		return this.data.get( "address" ).toString();
	}

	public String getCity() {
		return this.data.get( "city" ).toString();
	}

	public String getZip() {
		return this.data.get( "zip" ).toString();
	}

	public String getState() {
		return this.data.get( "stateName" ).toString();
	}

	public String getPhoneNumber() {
		return this.data.get( "phone" ).toString();
	}

	public String getBirthDate() {
		return this.data.get( "birthDate" ).toString();
	}

	public String getIdentityDoc() {
		return this.data.get( "identityDocument" ).toString();
	}

	public String getIdentityNum() {
		return this.data.get( "idDocumentNum" ).toString();
	}

	public String getEmergencyContact() {
		return this.data.get( "emergencyContact" ).toString();
	}

	public String getEmergencyPhone() {
		return this.data.get( "emergencyPhone" ).toString();
	}

	public int getVisa() {
		return Integer.parseInt( this.data.get( "visa" ).toString() );
	}

	public String getPhotoPortrait() {
		return this.data.get( "photoPortrait" ).toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if( this == obj )
			return true;
		if( obj == null )
			return false;
		if( getClass() != obj.getClass() )
			return false;
		User other = ( User ) obj;
		if( id != other.id )
			return false;
		return true;
	}

}
